package com.eralink.unionuhfreader;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import androidx.core.app.ActivityCompat;

import com.eralink.unionuhfreader.bean.AppMemberUserInfoRespVO;
import com.eralink.unionuhfreader.bean.Auth;
import com.eralink.unionuhfreader.bean.CashierDO;
import com.eralink.unionuhfreader.http.Api;
import com.eralink.unionuhfreader.http.JsonCallBack;
import com.eralink.unionuhfreader.http.Result;
import com.eralink.unionuhfreader.netty.OneCardListen;
import com.eralink.unionuhfreader.netty.chuankou.ChuanKouNetty;
import com.eralink.unionuhfreader.netty.chuankou.HeartBeatListener;
import com.eralink.unionuhfreader.util.ByteUtil;
import com.eralink.unionuhfreader.util.SharedPreferencesUtil;
import com.eralink.unionuhfreader.util.ToastUtil;
import com.lzy.okgo.BuildConfig;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.cache.CacheEntity;
import com.lzy.okgo.cache.CacheMode;
import com.lzy.okgo.https.HttpsUtils;
import com.lzy.okgo.model.HttpHeaders;
import com.lzy.okgo.model.HttpParams;
import com.lzy.okgo.model.Response;

import java.io.UnsupportedEncodingException;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;

import okhttp3.OkHttpClient;

public class MyApplication extends Application {
    private  static  MyApplication myApplication;
    public static Auth auth=new Auth();
    public  static CashierDO cashierDO;
    public static AppMemberUserInfoRespVO memberUserInfoRespVO;
    private OkGo okGo;
    private Handler handler=new Handler();
    @Override
    public void onCreate() {
        super.onCreate();
        myApplication=this;
        initOkgo();
        //每隔5秒 检查下当前token过期情况
        handler.postDelayed(runnable,1000*5);
        connect_oncard= (boolean) SharedPreferencesUtil.getData(this,key_onecard,false);
        NettyConnect();
    }
    public static String getRootPathOfWebAppData() {
        StringBuilder path = new StringBuilder();
        path.append(MyApplication.getInstance().getFilesDir().getAbsolutePath());
        path.append("/webapp/resources");
        return path.toString();
    }
    Runnable runnable=new Runnable() {
        @Override
        public void run() {
            if (auth!=null&&auth.getExpiresTime()<=System.currentTimeMillis()&&auth.getRefreshToken()!=null){
                Log.i("ykj520","tonken 过期");
                Api.refreshToken(new JsonCallBack<Result<Auth>>(){
                    @Override
                    public void onSuccess(Response<Result<Auth>> response) {
                        Result<Auth> body = response.body();
                        if (body.isSucess()) {
                            MyApplication.auth = body.getData();
                        }
                        handler.postDelayed(runnable,1000*5);
                    }
                });
            }else{
                handler.postDelayed(runnable,1000*5);
            }
        }
    };

    public static MyApplication getInstance(){
        return myApplication;
    }
    public void initOkgo() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        //全局的读取超时时间
        builder.readTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
        //全局的写入超时时间
        builder.writeTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
        //全局的连接超时时间
        builder.connectTimeout(OkGo.DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
        //方法一：信任所有证书,不安全有风险
        HttpsUtils.SSLParams sslParams1 = HttpsUtils.getSslSocketFactory();
        builder.sslSocketFactory(sslParams1.sSLSocketFactory, sslParams1.trustManager);
//---------这里给出的是示例代码,告诉你可以这么传,实际使用的时候,根据需要传,不需要就不传-------------//
        HttpHeaders headers = new HttpHeaders();
       // headers.put("Authorization", Authorization);    //header不支持中文，不允许有特殊字符
        headers.put("tenant-id","1");
        HttpParams params = new HttpParams();
//-------------------------------------------------------------------------------------//
        builder.hostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });
        okGo = OkGo.getInstance().init(this)                       //必须调用初始化
                .setOkHttpClient(builder.build())               //建议设置OkHttpClient，不设置将使用默认的
                .setCacheMode(CacheMode.NO_CACHE)               //全局统一缓存模式，默认不使用缓存，可以不传
                .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE)   //全局统一缓存时间，默认永不过期，可以不传
                .setRetryCount(3)                               //全局统一超时重连次数，默认为三次，那么最差的情况会请求4次(一次原始请求，三次重连请求)，不需要可以设置为0
                .addCommonHeaders(headers)                //全局公共头
                .addCommonParams(params);                       //全局公共参数
    }
    public static String getSn() {
        String sn = "";
        /*if (true){
            return "DA2420AW40895";
        }*/
        try {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
                sn = Build.SERIAL;
            } else {
                if (ActivityCompat.checkSelfPermission(MyApplication.getInstance(), Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                    // TODO: Consider calling
                    //    ActivityCompat#requestPermissions
                    // here to request the missing permissions, and then overriding
                    //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                    //                                          int[] grantResults)
                    // to handle the case where the user grants the permission. See the documentation
                    // for ActivityCompat#requestPermissions for more details.
                    Log.i("ykj520","sn:"+sn);
                    return sn;
                }else{
                    sn = Build.getSerial();
                }

            }
            if (sn!=null&&!sn.equals("")&&!sn.equals("unknown")){
                Log.i("ykj520","sn:"+sn);
                return sn;
            }else{
                if (BuildConfig.DEBUG){
                    return "1234567890";
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        String mac = null;
        try {
            mac = macAddress();
        } catch (SocketException e) {
            e.printStackTrace();
        }
        if (mac != null) {
            mac = mac.replace(":", "");
        }
        Log.i("ykj520","sn:"+mac);
        return mac;
    }
    public static String macAddress() throws SocketException {
        String address = null;
        // 把当前机器上的访问网络接口的存入 Enumeration集合中
        Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
        while (interfaces.hasMoreElements()) {
            NetworkInterface netWork = interfaces.nextElement();
            // 如果存在硬件地址并可以使用给定的当前权限访问，则返回该硬件地址（通常是 MAC）。
            byte[] by = netWork.getHardwareAddress();
            if (by == null || by.length == 0) {
                continue;
            }
            StringBuilder builder = new StringBuilder();
            for (byte b : by) {
                builder.append(String.format("%02X:", b));
            }
            if (builder.length() > 0) {
                builder.deleteCharAt(builder.length() - 1);
            }
            String mac = builder.toString();
            Log.d("mac", "interfaceName=" + netWork.getName() + ", mac=" + mac);
            // 从路由器上在线设备的MAC地址列表，可以印证设备Wifi的 name 是 wlan0
            if (netWork.getName().equals("wlan1")) {
                Log.d("mac", " interfaceName =" + netWork.getName() + ", mac=" + mac);
                address = mac;
                break;
            }
        }
        return address;
    }
    /*一卡通串口服务器TCP连接*/
    ChuanKouNetty client;
    public static boolean connect_oncard;
    private OneCardListen oneCardListen;
    public static final String key_onecard="onecard";
    public static final String key_onecard_ip="onecard_ip";
    public static final String key_onecard_port="onecard_port";
    public void NettyConnect(){
        if (client!=null){
            client.stop();
        }
        boolean b= (boolean) SharedPreferencesUtil.getData(this,key_onecard,false);
        if (!b||SharedPreferencesUtil.getData(this,key_onecard_ip,"").toString().equals("")){
            return;
        }
        String port=SharedPreferencesUtil.getData(this,key_onecard_port,"8899").toString();
        client = new ChuanKouNetty(SharedPreferencesUtil.getData(this,key_onecard_ip,"").toString(), Integer.valueOf(port));
        client.addHeartBeat(new HeartBeatListener() {
            @Override
            public byte[] getHeartBeat() {
                String data = "心跳";
                try {
                    client.sentData("测试数据".getBytes("GBK"));
                    return data.getBytes("GBK");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                return null;
            }
        });
        client.setHandler(handleronecard);
        client.start();
    }
    Handler handleronecard=new Handler(){
        @SuppressLint("HandlerLeak")
        @Override
        public void handleMessage(Message msg) {
            int what=msg.what;
            switch (what){
                case 1:
                    // 接收到数据 5A 0-2
                    // 00 15 包序号2-6
                    // 01 命令类别 6-8
                    // 52 命令码8-10
                    // 00 1A 数据长度10-14
                    // 00  返回码14-16

                    // 卡号 00 00 00 00 00 00 00 12 34 57  16-36
                    // 交易额 00 00 00 01  36-44
                    // 交易余额 00 00 01 0D 44-52
                    // 交易日期20 25 01 11 18 36 06 1D  7位

                    //5A  0-2
                    // 008A 2-6
                    // 01 命令码类别
                    // 52 命令码
                    // 00 1A 数据长度
                    // 00 返回码14 -16
                    // 00 00 00 00 00 00 00 00 00 03 16-36
                    // 00000A280000A0A020250115090129D2

                    //5A
                    // 0089
                    // 01
                    // 54
                    // 0001
                    // 00
                    // DD

                    String data=msg.obj.toString();
                    //上报数据
                    Api.uploadOnecardData(data,new JsonCallBack<String>(){
                        @Override
                        public void onSuccess(Response<String> response) {

                        }
                    });
                    if (data.startsWith("5A")){
                        //pos返回的数据
                        String sn=data.substring(2,6);
                        String returncode=data.substring(14,16);//返回码
                        String cmd=data.substring(8,10);//命令码
                        if (returncode.equals("00")){
                            //成功
                            long datalenght= ByteUtil.hexStr2decimal(data.substring(10,14));
                            Log.i("ykj520","支付成功 数据长度"+datalenght);
                            String usercode="";
                            long money=0;
                            if (cmd.equals("52")){
                                //支付成功回调
                                if (datalenght==26){
                                    //00 00 00 00 00 00 00 12 34 57 00 00 00 01 00 00 01 0D 20 25 01 11 18 36 06 1D
                                    // String info=data.substring(16,data.length()-2);
                                    //String username= info.substring(0,20);
                                    usercode=data.substring(16,36);
                                    money=ByteUtil.hexStr2decimal(data.substring(36,44));
                                }else if (datalenght>=60){
                                    //String username=data.substring(16,36);//姓名
                                    // String code=data.substring(36,46);//工号
                                    usercode=data.substring(46,56);//卡号
                                    money=ByteUtil.hexStr2decimal(data.substring(56,60));
                                }else{

                                }
                                if (oneCardListen!=null){
                                    if (usercode==null||usercode.equals("")){
                                        usercode="0000";
                                    }
                                    oneCardListen.payCallBack(usercode,money,sn);
                                }
                                Log.i("ykj520","交易成功卡号："+usercode+" 交易金额:"+money+"分");
                            } else if (cmd.equals("54")){
                                Log.d("ykj520","取消扣费成功");
                            }else{
                                ToastUtil.showToast("支付返回值错误：数据长度："+datalenght);
                            }

                        }else if (returncode.equals("01")){
                            //校验失败
                            Log.e("ykj520","校验失败");
                            ToastUtil.showToast("交易校验失败");
                        }else {
                            Log.e("ykj520","交易失败"+returncode);
                            ToastUtil.showToast("交易校验失败"+returncode);
                        }
                    }
                    break;
            }
            super.handleMessage(msg);
        }
    };
    public void setOneCardListen(OneCardListen oneCardListen) {
        this.oneCardListen = oneCardListen;
    }
    public void sendData(byte[] bytes){
        if (client!=null){
            client.sentData(bytes);
        }
    }
    public void cancelPaydata() {
        if (!MyApplication.connect_oncard) {
            return;
        }
        int sn = (int) SharedPreferencesUtil.getData(this, "sn", -1);
        if (sn == 65535) {
            sn = 0;
        } else {
            sn = sn + 1;
        }
        //5A 00 01 01 A2 00 04 00 00 00 04 A2
        byte[] data = new byte[10];
        //包序号
        String hexString = Integer.toHexString(sn);
        int datalen = 4 - hexString.length();
        for (int i = 0; i < datalen; i++) {
            hexString = "0" + hexString;
        }
        //byte[] data={0x00, 0x01,0x01, (byte) 0xA2, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04};
        byte[] byteArray = ByteUtil.hexStr2bytes(hexString);
        data[0] = byteArray[0];
        data[1] = byteArray[1];//包序号
        data[2] = (byte) 0x01;//命令类别
        data[3] = (byte) 0xA4;//命令码
        byte LRC = ByteUtil.calculateLRC(data);
        byte[] sendata = new byte[6];
        sendata[0] = (byte) 0x5A;
        for (int i = 1; i < 5; i++) {
            sendata[i] = data[i - 1];
        }
        sendata[5] = LRC;
        MyApplication.getInstance().sendData(sendata);
        Log.i("ykj520", "发送数据序列号:" + ByteUtil.bytes2HexStr(sendata));
        SharedPreferencesUtil.saveData(this, "sn", sn);
    }
}
